package pers.zero.jwt.spring.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import pers.zero.jwt.entity.UserPrinciple;
import pers.zero.jwt.spring.UserPrincipleManager;
import pers.zero.jwt.spring.config.JwtConfig;
import pers.zero.jwt.util.JwtClientUtil;
import pers.zero.util.collection.MapUtil;
import pers.zero.util.servlet.ResponseUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <h3>spring需要扫描包： pers.zero.jwt</h3>
 * <p><b>
 * jwt 过滤器 <br/>
 * </b></p>
 * <br/>
 * <pre>
 *  code 状态
 *      -1 未登录
 *      -2 token 过期
 * </pre>
 * 创建时间: 9/2/2019 4:22 PM
 *
 * @author Zero
 */
@Component
public class JwtTokenInterceptor implements HandlerInterceptor {

    @Autowired(required = false)
    private JwtConfig config;

    /**
     * options 请求，直接放行
     */
    private final String OPTIONS_METHOD = "OPTIONS";

    /**
     * 超时时间 毫秒
     */
    private final long TIME_OUT_MILLS = 1800000L;


    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {


        // options 请求，直接返回
        if (OPTIONS_METHOD.equalsIgnoreCase(request.getMethod())) {

            return true;
        }


        UserPrinciple principle = UserPrincipleManager.setUserPrinciple(request);
        if (principle == null) {
            // 用户为空
            ResponseUtil.writeJson(response,
                    MapUtil.createMap(
                            "state", "error",
                            "code", -1,
                            "msg", "未登录."
                    ));
            return false;
        } else if (!principle.isMobile()) {
            // 用户不为空， 可执行其他 验证。
            // 验证时间戳
            long timestamp = principle.getTimestamp();
            if (System.currentTimeMillis() - timestamp >= TIME_OUT_MILLS) {
                ResponseUtil.writeJson(response,
                        MapUtil.createMap(
                                "state", "error",
                                "code", -2,
                                "msg", "登录过期,请重新登录."
                        ));
                // 验证失败，移除 变量信息
                UserPrincipleManager.removeUserPrinciple();
                return false;
            }


            // 验证通过 , 更新 token
            updateToken(response);
            return true;
        } else {
            // 验证通过

            return true;
        }

    }

    /**
     * 更新 token
     *
     * @param response 响应信息
     */
    private void updateToken(HttpServletResponse response) {

        // 更新 token
        UserPrinciple principle = UserPrincipleManager.getUpdatePrinciple();

        if (principle == null) {
            return;
        }


        // 更新 token,放在响应头中
        response.setHeader("refresh-token", JwtClientUtil.makeToken(principle));


    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        // 清空 ThreadLocal
        UserPrincipleManager.removeUserPrinciple();
    }
}
